/**
 * 认证状态管理 - 使用Pinia，遵循苹果设计的简洁理念
 */

import { defineStore } from 'pinia'
import { ref, computed, readonly } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import type { 
  User, 
  LoginRequest, 
  LoginResponse, 
  JWTPayload,
  PermissionContext 
} from '@/types/rbac'
import { authApi } from '@/api/auth'

// JWT工具函数
function parseJWT(token: string): JWTPayload | null {
  try {
    const base64Url = token.split('.')[1]
    const base64 = base64Url.replace(/-/g, '+').replace(/_/g, '/')
    const jsonPayload = decodeURIComponent(
      atob(base64)
        .split('')
        .map(c => '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2))
        .join('')
    )
    return JSON.parse(jsonPayload)
  } catch {
    return null
  }
}

function isTokenExpired(token: string): boolean {
  const payload = parseJWT(token)
  if (!payload) return true
  
  const now = Math.floor(Date.now() / 1000)
  return payload.exp < now
}

export const useAuthStore = defineStore('auth', () => {
  // 状态
  const user = ref<User | null>(null)
  const token = ref<string>('')
  const refreshToken = ref<string>('')
  const permissions = ref<string[]>([])
  const roles = ref<string[]>([])
  const isLoading = ref(false)
  const lastActivity = ref<number>(Date.now())

  // 从localStorage恢复状态
  const initializeFromStorage = () => {
    const storedToken = localStorage.getItem('auth_token')
    const storedRefreshToken = localStorage.getItem('refresh_token')
    const storedUser = localStorage.getItem('user_info')
    const storedPermissions = localStorage.getItem('user_permissions')
    const storedRoles = localStorage.getItem('user_roles')

    if (storedToken && !isTokenExpired(storedToken)) {
      token.value = storedToken
      refreshToken.value = storedRefreshToken || ''
      
      if (storedUser) {
        try {
          user.value = JSON.parse(storedUser)
        } catch {
          clearStorage()
        }
      }
      
      if (storedPermissions) {
        try {
          permissions.value = JSON.parse(storedPermissions)
        } catch {
          permissions.value = []
        }
      }
      
      if (storedRoles) {
        try {
          roles.value = JSON.parse(storedRoles)
        } catch {
          roles.value = []
        }
      }
    } else {
      clearStorage()
    }
  }

  // 清除本地存储
  const clearStorage = () => {
    localStorage.removeItem('auth_token')
    localStorage.removeItem('refresh_token')
    localStorage.removeItem('user_info')
    localStorage.removeItem('user_permissions')
    localStorage.removeItem('user_roles')
  }

  // 保存到本地存储
  const saveToStorage = () => {
    if (token.value) {
      localStorage.setItem('auth_token', token.value)
      localStorage.setItem('refresh_token', refreshToken.value)
      
      if (user.value) {
        localStorage.setItem('user_info', JSON.stringify(user.value))
      }
      
      if (permissions.value.length > 0) {
        localStorage.setItem('user_permissions', JSON.stringify(permissions.value))
      }
      
      if (roles.value.length > 0) {
        localStorage.setItem('user_roles', JSON.stringify(roles.value))
      }
    }
  }

  // 计算属性
  const isAuthenticated = computed(() => {
    return Boolean(token.value && user.value && !isTokenExpired(token.value))
  })

  const userDisplayName = computed(() => {
    return user.value?.real_name || user.value?.username || '未知用户'
  })

  const isSuperUser = computed(() => {
    return Boolean(user.value?.is_superuser)
  })

  const permissionContext = computed((): PermissionContext => ({
    user_id: user.value?.id || 0,
    roles: roles.value,
    permissions: permissions.value,
    resources: [], // TODO: 获取可访问资源
    department: user.value?.department,
    is_superuser: isSuperUser.value
  }))
  
  // Actions
  const login = async (loginForm: any): Promise<boolean> => {
    isLoading.value = true
    
    try {
      // 映射登录表单到API请求格式
      const credentials: LoginRequest = {
        username: loginForm.username,
        password: loginForm.password,
        remember_me: false,
        captcha_code: loginForm.captcha_code,
        session_id: loginForm.session_id
      }
      
      const response = await authApi.login(credentials)
      
      if (response.success) {
        const loginData = response.data as LoginResponse
        
        // 保存认证信息
        token.value = loginData.access_token
        refreshToken.value = loginData.refresh_token
        user.value = loginData.user_info
        
        // 获取用户权限和角色（即使失败也不影响登录）
        try {
          await loadUserPermissions()
        } catch (error) {
          console.warn('权限加载失败，但登录继续:', error)
        }
        
        // 保存到本地存储
        saveToStorage()
        
        // 更新最后活动时间
        lastActivity.value = Date.now()
        
        ElMessage.success(`欢迎回来，${userDisplayName.value}！`)
        return true
      }
      
      return false
    } catch (error: any) {
      console.error('登录失败:', error)
      
      // 处理业务逻辑错误（success=false的情况）
      if (error.message) {
        ElMessage.error(error.message)
        // 抛出错误以便登录组件处理验证码逻辑
        throw new Error(error.message)
      }
      
      // 处理HTTP错误响应
      if (error?.response?.status === 401) {
        const errorMessage = error.response.data?.detail || error.message
        ElMessage.error(errorMessage)
        
        // 抛出错误以便登录组件处理验证码逻辑
        throw new Error(errorMessage)
      } else {
        ElMessage.error('登录服务异常，请稍后重试')
      }
      
      return false
    } finally {
      isLoading.value = false
    }
  }

  const logout = async (showMessage = true): Promise<void> => {
    try {
      // 调用登出API
      if (token.value) {
        await authApi.logout()
      }
    } catch (error) {
      console.error('登出API调用失败:', error)
    } finally {
      // 清除本地状态
      user.value = null
      token.value = ''
      refreshToken.value = ''
      permissions.value = []
      roles.value = []
      
      // 清除本地存储
      clearStorage()
      
      if (showMessage) {
        ElMessage.success('已安全退出登录')
      }
    }
  }

  const refreshAccessToken = async (): Promise<boolean> => {
    if (!refreshToken.value) return false
    
    try {
      const response = await authApi.refreshToken(refreshToken.value)
      
      if (response.success) {
        token.value = response.data.access_token
        refreshToken.value = response.data.refresh_token || refreshToken.value
        
        saveToStorage()
        return true
      }
      
      return false
    } catch (error) {
      console.error('刷新token失败:', error)
      await logout(false)
      return false
    }
  }

  const loadUserPermissions = async (): Promise<void> => {
    if (!user.value) return
    
    try {
      const response = await authApi.getUserPermissions()
      
      if (response.success) {
        permissions.value = response.data.permissions
        roles.value = response.data.roles.map(role => role.code)
      }
    } catch (error) {
      console.error('获取用户权限失败:', error)
      permissions.value = []
      roles.value = []
    }
  }

  const updateUserInfo = async (): Promise<void> => {
    if (!user.value) return
    
    try {
      const response = await authApi.getCurrentUser()
      
      if (response.success) {
        user.value = response.data
        saveToStorage()
      }
    } catch (error) {
      console.error('更新用户信息失败:', error)
    }
  }

  const checkPermission = (permission: string): boolean => {
    if (isSuperUser.value) return true
    return permissions.value.includes(permission)
  }

  const hasRole = (role: string): boolean => {
    if (isSuperUser.value) return true
    return roles.value.includes(role)
  }

  const hasAnyPermission = (permissionList: string[]): boolean => {
    if (isSuperUser.value) return true
    return permissionList.some(permission => permissions.value.includes(permission))
  }

  const hasAllPermissions = (permissionList: string[]): boolean => {
    if (isSuperUser.value) return true
    return permissionList.every(permission => permissions.value.includes(permission))
  }

  const updateActivity = (): void => {
    lastActivity.value = Date.now()
  }

  const checkTokenExpiry = (): boolean => {
    if (!token.value) return false
    
    if (isTokenExpired(token.value)) {
      // 尝试刷新token
      refreshAccessToken().catch(() => {
        logout(false)
      })
      return false
    }
    
    return true
  }

  // 初始化
  initializeFromStorage()

  // 定期检查token有效性
  setInterval(() => {
    if (isAuthenticated.value) {
      checkTokenExpiry()
    }
  }, 60000) // 每分钟检查一次

  // 监听用户活动
  const activityEvents = ['mousedown', 'mousemove', 'keypress', 'scroll', 'touchstart']
  activityEvents.forEach(event => {
    document.addEventListener(event, updateActivity, { passive: true })
  })

  return {
    // 状态
    user: readonly(user),
    token: readonly(token),
    permissions: readonly(permissions),
    roles: readonly(roles),
    isLoading: readonly(isLoading),
    lastActivity: readonly(lastActivity),
    
    // 计算属性
    isAuthenticated,
    userDisplayName,
    isSuperUser,
    permissionContext,
    
    // 方法
    login,
    logout,
    refreshAccessToken,
    loadUserPermissions,
    updateUserInfo,
    checkPermission,
    hasRole,
    hasAnyPermission,
    hasAllPermissions,
    updateActivity,
    checkTokenExpiry
  }
})

export default useAuthStore